﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "CmdCreateGridNewByPick.h"
#include "GmUiStructureCommandRegister.h"
#include "StructureCmdIds.h"
#include "IModelView.h"
#include "IPlane.h"
#include "GbmpModelViewTypes.h"
#include "UiCommonDialog.h"
#include "AddStructureDynamicPannelUtil.h"
#include "IUserTransaction.h"
#include "PickCurveDrawGridNewBehavior.h"
#include "GbmpBuiltInCategoryUniIdentitiesNew.h"
#include "GbmpPresetParameterUIUtils.h"
#include "IGridNew.h"
#include "GbmpQuickCast.h"
#include "ILine2d.h"
#include "GridNameManager.h"
#include "IGenericElement.h"
#include "UserTransactionGroupUtils.h"
#include "IDocument.h"
#include "GbmpControlIds.h"
#include "GridNewInput.h"
#include "GcmpActionBase.h"
#include "StructureInstancePresetParameterUtils.h"
#include "GridNewUtils.h"
#include "UiDocumentViewUtils.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"
using namespace gcmp;

REGISTER_GM_COMMAND(CmdCreateGridNewByPick)

CmdCreateGridNewByPick::CmdCreateGridNewByPick()
    : CmdCreateElementByPick(ID_CMD_CREATE_GRID_NEW_BY_PICK), m_utxGroupIdx(0)
{
    
}

bool CmdCreateGridNewByPick::OnExecuteCommand()
{
    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");
    const std::wstring& viewType = pModelView->GetUserDataId();

    if (PlanViewType != viewType && View3DViewType != viewType)
    {
        UiCommonDialog::ShowMessageBox(GBMP_TR(L"创建轴网"), GBMP_TR(L"此视图下不支持创建轴网"), (int)UiCommonDialog::ButtonType::OK);
        return false;
    }

    return true;
}

void CmdCreateGridNewByPick::SetupRibbonContextualPanel()
{
    AddStructureDynamicPannelUtil::SetupGridNewCreationContext(m_pPickCurveAction, ID_PAGE_GBMP_MODIFY);
}

OwnerPtr<PickCurveDrawElementBehavior> CmdCreateGridNewByPick::CreateActionDrawCurvePickBehavior()
{
    OwnerPtr<PickCurveDrawGridNewBehavior> opGridNewBehavior = NEW_AS_OWNER_PTR(PickCurveDrawGridNewBehavior, UiDocumentViewUtils::GetCurrentDocument());
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opGridNewBehavior, L"opGridNewBehavior为空",L"GDMPLab",L"2024-03-30");
    opGridNewBehavior->SetOnCurvePickedCallback(PickCurveDrawElementBehavior::CreateOnCurvePickedCallback(&CmdCreateGridNewByPick::OnCurvePicked, this));

    return TransferOwnership(opGridNewBehavior);
}

bool CmdCreateGridNewByPick::CreatePresetElement(ElementId& elementId)
{
    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");
    
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    GridNewInput gridNewInput;
    gridNewInput.Document = pDoc;
    gridNewInput.Visible = false;
    OwnerPtr<IPlane> opIPlane = pModelView->GetWorkPlane();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opIPlane, L"opIPlane为空",L"GDMPLab",L"2024-03-30");
    gridNewInput.verticalExtents = GridNewUtils::GetGridDefaultVerticalExtents(pDoc, opIPlane.get(), ElementCreationOptions::Transient);
    GridNewUtils::setGridNewPresetParameter(pDoc,gridNewInput.StartTagVisble, gridNewInput.EndTagVisble);
    gridNewInput.CreationOption = ElementCreationOptions::Transient;
 
    // 创建临时的线用来刷新属性面板,使用默认的属性
    OwnerPtr<ICurve2d> opCurve = ILine2d::Create(Vector2d(0.0, 0.0), Vector2d(1.0, 0.0));
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opCurve, L"opArc为空",L"GDMPLab",L"2024-03-30");
    gridNewInput.VecOpCurve.push_back(TransferOwnership(opCurve));

    // 创建预设轴网
    IGridNew* pPresetGridNew = IGridNew::Create(gridNewInput);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetGridNew, L"pPresetGridNew为空",L"GDMPLab",L"2024-03-30");
    //获取除了轴号的属性面板参数   
    elementId = pPresetGridNew->GetOwnerElement()->GetElementId();

    return true;
}

bool CmdCreateGridNewByPick::OnCurvePicked(IUiView* pCurrentView, OwnerPtr<ICurve2d> opCurve2d)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pCurrentView, L"pCurrentView为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opCurve2d, L"opCurve2d为空",L"GDMPLab",L"2024-03-30");
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    GridNewInput gridNewInput;
    gridNewInput.Document = pDoc;
    gridNewInput.Visible = true;
    OwnerPtr<IPlane> opIPlane = pModelView->GetWorkPlane();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opIPlane, L"opIPlane为空",L"GDMPLab",L"2024-03-30");
    gridNewInput.verticalExtents = GridNewUtils::GetGridDefaultVerticalExtents(pDoc, opIPlane.get(), ElementCreationOptions::Normal);
    GridNewUtils::setGridNewPresetParameter(pDoc,gridNewInput.StartTagVisble, gridNewInput.EndTagVisble);
    gridNewInput.CreationOption = ElementCreationOptions::Normal;
    gridNewInput.VecOpCurve.push_back(TransferOwnership(opCurve2d));

    OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(pDoc, GBMP_TR(L"创建轴网"));
    IGridNew* pGridNew = IGridNew::Create(gridNewInput);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pGridNew, L"pGridNew为空",L"GDMPLab",L"2024-03-30");
    //获取预设轴网id
    ElementId presetGridId = m_pPickCurveAction->GetPreSetElementId();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(presetGridId.IsValid(), L"presetGridElement为空",L"GDMPLab",L"2024-03-30");
    IElement *presetGridElement = pDoc->GetElement(presetGridId);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(presetGridElement, L"presetGridElement为空",L"GDMPLab",L"2024-03-30");
    IGenericElement* pPresetGenericElement = quick_cast<IGenericElement>(presetGridElement);
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pPresetGenericElement, L"pPresetGenericElement为空",L"GDMPLab",L"2024-03-30");
    IGridNew* pPresetGrid = quick_cast<IGridNew>(pPresetGenericElement->GetExternalObject());
    
    //根据预设轴网的name更新当前轴网name
    pGridNew->SetName(pPresetGrid->GetName());

    //提交事务
    ut->Commit();

    //设置预设轴网的下一个名字并刷新属性面板
    pPresetGrid->AutoName();
    GbmpPresetParameterUIUtils::UpdatePropertyPanel(presetGridId);

    // 提交事务组并合并为一个事务
    UserTransactionGroupUtils::CommitLatestActiveWithTransactionsMergedIntoOne(UiDocumentViewUtils::GetCurrentDocument());
    // 启动新的事务组
    UserTransactionGroupUtils::Start(UiDocumentViewUtils::GetCurrentDocument(), GBMP_TR(L"创建单条轴网事务组"), m_utxGroupIdx);
    return true;
}

bool CmdCreateGridNewByPick::OnInitAction(IUiView* pCurrentView)
{
    IDocument* pDoc = UiDocumentViewUtils::GetCurrentModelView()->GetDocument();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    // 启动轴网事务组
    UserTransactionGroupUtils::Start(pDoc, GBMP_TR(L"轴网事务组"), m_utxGroupIdx);

    // 初始化预设参数
    OwnerPtr<IUserTransaction> opTransaction = IUserTransaction::Create(pDoc, GBMP_TR(L"设置轴网预设参数"), true);
    StructureInstancePresetParameterUtils::SetPresetInstanceType(pDoc, GetCategory(), 0, ElementId::InvalidID);
    opTransaction->Commit();

    CmdCreateElementByPick::OnInitAction(pCurrentView);

    return true;
}

bool CmdCreateGridNewByPick::OnDestroyAction()
{
    CmdCreateElementByPick::OnDestroyAction();

    UserTransactionGroupUtils::Abort(UiDocumentViewUtils::GetCurrentDocument(), m_utxGroupIdx);

    return true;
}

UniIdentity CmdCreateGridNewByPick::GetCategory() const
{
    return BuiltInCategoryUniIdentities::BICU_NEW_GRID;
}
